# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import ValidationError


class CpqBomLine(models.Model):
    """ＢＯＭ明细行 - 支持奔驰和小米两种格式"""
    _name = 'cpq.bom.line'
    _description = 'BOM明细行'
    _order = 'bom_id, sequence, id'
    _rec_name = 'display_name'
    _parent_name = 'parent_id'
    _parent_store = True

    # 关联
    bom_id = fields.Many2one(
        'cpq.bom',
        string='BOM版本',
        required=True,
        ondelete='cascade',
        index=True
    )
    project_id = fields.Many2one(
        'cpq.project',
        string='项目',
        related='bom_id.project_id',
        store=True,
        index=True
    )
    
    # 系统唯一ID (核心⭐) - 格式: PRJ001-V2-0015
    unique_id = fields.Char(
        string='系统ID',
        compute='_compute_unique_id',
        store=True,
        index=True,
        help='系统生成的唯一标识,用于版本对比追溯'
    )
    
    # 序号和层级
    sequence = fields.Integer(
        string='顺序号',
        default=10,
        help='用于排序'
    )
    row_number = fields.Integer(
        string='行号',
        help='在Excel中的行号'
    )
    level_number = fields.Char(
        string='层级编号',
        help='层次结构编号: 1, 1.1, 1.1.1, 1.2, 2, 2.1...'
    )
    level = fields.Integer(
        string='层级',
        default=1,
        help='层级深度: 1=一级, 2=二级, 3=三级...'
    )
    
    # 父子关系（用于树形视图）
    parent_id = fields.Many2one(
        'cpq.bom.line',
        string='父级零件',
        ondelete='cascade',
        index=True,
        help='用于树形结构展示'
    )
    parent_path = fields.Char(
        index=True,
        help='用于父子关系存储'
    )
    child_ids = fields.One2many(
        'cpq.bom.line',
        'parent_id',
        string='子级零件'
    )
    
    # 显示名称（用于树形视图展示）
    display_name = fields.Char(
        string='显示名称',
        compute='_compute_display_name',
        store=True
    )
    
    # 零件标识信息
    part_number = fields.Char(
        string='零件号',
        help='可以为空(XX)或未提供'
    )
    part_name = fields.Char(
        string='零件名称',
        required=True,
        help='必填字段'
    )
    lu_part_number = fields.Char(
        string='LU零件号',
        help='奔驰格式: 一级零件号'
    )
    lu_part_name = fields.Char(
        string='LU零件名称',
        help='奔驰格式: 一级零件名称'
    )
    
    # 制造属性
    make_or_buy = fields.Selection([
        ('L', '自制'),
        ('P', '外采')
    ], string='自制/外采', help='L=自制, P=外采')
    
    process_type = fields.Selection([
        ('injection', '注塑'),
        ('painting', '喷涂'),
        ('injection_painting', '注塑+喷涂'),
        ('assembly', '装配'),
        ('metal', '金属件'),
        ('foam', '发泡件'),
        ('other', '其他')
    ], string='生产工艺')
    
    # 物理属性 (成本计算关键参数⭐)
    weight = fields.Float(
        string='克重(g)',
        digits=(16, 3),
        help='单件克重,影响材料成本'
    )
    surface_area = fields.Float(
        string='涂装面积(dm²)',
        digits=(16, 2),
        help='影响喷涂成本'
    )
    material = fields.Char(
        string='材料',
        help='如: PP增强, PPE, PC+ABS'
    )
    material_standard = fields.Char(
        string='材料标准',
        help='材料规格标准'
    )
    thickness = fields.Float(
        string='壁厚(mm)',
        digits=(16, 2)
    )
    dimensions = fields.Char(
        string='外形尺寸',
        help='长×宽×高 mm'
    )
    
    # 表面处理
    surface_treatment = fields.Char(
        string='表面处理',
        help='如: 喷涂, 电镀, 素色'
    )
    surface_standard = fields.Char(
        string='表面处理标准'
    )
    
    # 配置和状态
    configuration = fields.Char(
        string='配置及数量',
        help='如: 标配, 选配'
    )
    assembly_level = fields.Char(
        string='总成级别',
        help='如: 00, 01, 02'
    )
    part_status = fields.Selection([
        ('new', 'NEW'),
        ('carryover', 'CARRYOVER'),
        ('modified', 'MODIFIED')
    ], string='零件状态')
    
    # CODE标识 (奔驰格式特有)
    code = fields.Char(
        string='CODE',
        help='奔驰格式的配置代码'
    )
    
    # 图片
    picture = fields.Binary(
        string='图片',
        attachment=True,  # 存储为附件，避免直接存储base64
        help='零件图片'
    )
    picture_filename = fields.Char(string='图片文件名')
    
    # 版本对比字段⭐
    change_type = fields.Selection([
        ('none', '无变化'),
        ('new', '新增'),
        ('modified', '修改'),
        ('deleted', '删除')
    ], string='变化类型', default='none', help='用于版本对比标识')
    
    previous_line_id = fields.Many2one(
        'cpq.bom.line',
        string='原版本行',
        help='对应的旧版本BOM行'
    )
    change_fields = fields.Char(
        string='变化字段',
        help='如: weight,material,process_type'
    )
    change_summary = fields.Text(
        string='变化摘要',
        compute='_compute_change_summary'
    )
    
    # 成本相关字段 (预留,后续实现)
    unit_cost = fields.Monetary(
        string='单件成本',
        currency_field='currency_id'
    )
    currency_id = fields.Many2one(
        'res.currency',
        string='币种',
        default=lambda self: self.env.company.currency_id
    )
    
    # 备注
    notes = fields.Text(string='备注')
    
    @api.depends('project_id.code', 'bom_id.version_sequence', 'sequence')
    def _compute_unique_id(self):
        """生成系统唯一ID"""
        for line in self:
            if line.project_id and line.bom_id:
                project_code = line.project_id.code or 'PRJ'
                version_seq = line.bom_id.version_sequence or 1
                line_seq = line.sequence or 0
                line.unique_id = f"{project_code}-V{version_seq}-{line_seq:04d}"
            else:
                line.unique_id = False
    
    @api.depends('part_number', 'part_name', 'level_number')
    def _compute_display_name(self):
        """计算显示名称：层级编号 + 零件号 + 零件名称"""
        for line in self:
            parts = []
            if line.level_number:
                parts.append(f"[{line.level_number}]")
            if line.part_number:
                parts.append(line.part_number)
            if line.part_name:
                parts.append(line.part_name)
            
            line.display_name = ' '.join(parts) if parts else f'BOM Line {line.id}'
    
    @api.depends('change_type', 'change_fields', 'previous_line_id')
    def _compute_change_summary(self):
        """生成变化摘要"""
        for line in self:
            if line.change_type == 'new':
                line.change_summary = '新增零件'
            elif line.change_type == 'deleted':
                line.change_summary = '删除零件'
            elif line.change_type == 'modified' and line.change_fields:
                fields_map = {
                    'weight': '克重',
                    'material': '材料',
                    'process_type': '工艺',
                    'surface_area': '面积',
                    'surface_treatment': '表面处理'
                }
                changed = []
                for field in line.change_fields.split(','):
                    field_name = fields_map.get(field.strip(), field.strip())
                    changed.append(field_name)
                line.change_summary = f"修改: {', '.join(changed)}"
            else:
                line.change_summary = False
    
    def name_get(self):
        """显示名称"""
        result = []
        for line in self:
            name = line.part_name or 'BOM Line'
            if line.part_number:
                name = f"[{line.part_number}] {name}"
            if line.unique_id:
                name = f"{line.unique_id}: {name}"
            result.append((line.id, name))
        return result
